home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "path.h"
-
- static char RCSid[] = "$Header: getpath.c,v 3.4 86/02/05 13:41:26 essick Exp $";
-
- extern int Debug; /* in mainlines */
-
-
- /*
- * char *getpath(dest) char *dest;
- *
- * look in the routing tables for a path from here to that
- * specified host. Return the path.
- * Return NULL if there is no such path.
- *
- * The returned path is of the form:
- * a!b!c!d!dest! (note trailing !)
- *
- * The path is saved in a static buffer so you have to save
- * it or it is destroyed in the next call.
- *
- * A re-write of what Jeff Donnelly did a while back.
- * Ray Essick
- *
- * The routing table contains lines of the form:
- * site<space>path
- * site = destination site
- * path = a!b!c!d!site! (note trailing !)
- *
- * Must be in alphabetical order since the search gives up
- * after finding a site "after" the one we want!
- */
-
- FILE * fopen ();
- extern char *fgets ();
-
- static int Dbm_Ready = 0; /* whether init'ed */
- static char *PathMap = PATHTABLE; /* path file */
-
- char *getpath (dest)
- char *dest;
- {
-
- static char line[BUFSIZ];
- FILE * mapfile;
- register char *p,
- *path;
-
-
- #ifdef DBM
- /*
- * A version of this routine which works with the set of routines
- * described in dbm(3x).
- *
- * Assumes that someone else is keeping the path tables correctly
- * updated (e.g., does a re-build on the table).
- */
- {
- struct datum contents; /* returning to him */
- struct datum key; /* fetch on this */
-
- if (!Dbm_Ready)
- {
- if (dbminit (PathMap) < 0) /* failed */
- goto hardway; /* try manually */
- Dbm_Ready++; /* mark ready */
- }
- key.dptr = dest; /* build fetch key */
- key.dsize = strlen (dest) + 1;
-
- contents = fetch (key); /* grab it */
- if (contents.dptr == (char *) NULL)
- goto checkstamps; /* try again */
- if (contents.dsize == 0) /* empty! */
- return ""; /* convert to null string */
- return (contents.dptr); /* give him the path */
- }
-
- checkstamps: /* failure above */
- /*
- * check the time stamps and complain if they are outdated
- * so that someone will fix them. If they are correct,
- * then we should merely return failure
- */
- {
- char name[1024];
- struct stat stat1,
- stat2;
-
- sprintf (name, "%s.dir", PathMap); /* db file */
- if (stat (name, &stat1) < 0) /* no db file */
- goto hardway; /* force it */
- if (stat (name, &stat2) < 0) /* no raw file */
- return (char *) NULL;
- if (stat1.st_mtime >= stat2.st_mtime) /* current */
- {
- return (char *) NULL;
- }
- else
- {
- /*
- * could do something about a message to inform
- * somebody that the database is out of date
- */
- }
- }
-
- hardway: /* failure above */
- /*
- * no database or out of date Do it by hand
- * and very s...l...o...w...l...y
- *
- * This algorithm should really do some sort of binary
- * search...
- */
- #endif DBM
-
- if ((mapfile = fopen (PathMap, "r")) == NULL)
- return ((char *) NULL); /* no file */
-
- while (fgets (line, BUFSIZ, mapfile) != NULL)
- {
- p = line;
- path = NULL;
- do
- {
- switch (*p)
- {
- case ' ':
- case '\t': /* zap and mark path */
- if (path == NULL) /* only once */
- {
- *p++ = '\0';
- path = p;
- }
- else
- p++; /* gotta move over it */
- break;
-
- case '\n':
- *p = '\0'; /* end of it all */
- break;
-
- default:
- p++;
- break;
- }
- }
- while (*p); /* terminates after newline */
- if (strcmp (line, dest) == 0) /* matches */
- {
- break; /* jump and return */
- }
-
- if (strcmp (line, dest) > 0) /* past it */
- {
- path = NULL;
- break;
- }
- }
- fclose (mapfile); /* don't litter */
- return (path); /* and our answer */
- }
-
- /*
- * setpathfile(name)
- * char *name;
- *
- * set the DBM file used by the getpath routine to something
- * else. Close one if already open.
- */
-
- setpathfile (name)
- char *name;
- {
- extern char *strsave ();
- if (Dbm_Ready)
- {
- Dbm_Ready = 0;
- /*
- * -ldbm makes no provision for closing the database
- */
- }
- PathMap = strsave (name); /* save it */
- }
-
- struct findpath_f *findpath (name)
- char *name;
- {
- register char *partial;
- register char *original;
- register char *path;
- register int fullroute;
-
- static struct findpath_f results;
- char *strsave(),
- *index();
-
- if (name == (char *) NULL)
- return (struct findpath_f *) NULL;
- original = partial = strsave (name);
- path = (char *) NULL;
- fullroute = 1;
- while (partial && *partial)
- {
- path = getpath (partial); /* probe for a path */
- if (Debug)
- fprintf (stderr, "Route to %s is %s\n",
- partial,
- path == (char *) NULL ? "(null)" : path);
- if (path != (char *) NULL) /* good - break */
- break;
- partial++; /* skip current dot */
- partial = index (partial, '.'); /* scan for dot */
- fullroute = 0; /* no longer complete */
- }
- if (path == (char *) NULL)
- return (struct findpath_f *) NULL; /* nothing */
- results.fp_path = strsave (path);
- results.fp_matched = strsave (partial);
- results.fp_fullroute = fullroute;
- return (&results);
- }
-